/*

  路由的导航守卫

  1.全局导航守卫
    3.x
      router.beforeEach(to,from,next)=>{}
      to:即将进入的页面

      from:即将离开的页面

      next():方法
        next() | next(true) | 不写 ==> 放行

        next(false) |不写next ==> 不放行:进不去即将进入的页面

        next(path) | next({}) ==> 重定向

    4.x
      router.beforeEach(to,from)=>{}
      to:即将进入的页面

      from:即将离开的页面

      return:
        return true ==> 放行

        return false ==> 不放行:进不去即将进入的页面

        rerturn path | return {} ==> 重定向

    1.1 全局前置守卫
        router.beforeEach(to,from)=>{

        }

    1.2 全局后置守卫
      router.afterEach((to, from) => {
        
      })

  2.独享守卫

  beforeEnter: (to, from) => {
            console.log('独享守卫写在路由配置中')
            return true
          },

  3.组件内置守卫

    3.1 进入前
      beforeRouteEnter(to, from) {
        // 在渲染该组件的对应路由被验证前调用
        // 不能获取组件实例 `this` ！
        // 因为当守卫执行时，组件实例还没被创建！
      },

    3.2  在当前路由改变，但是该组件被复用时调用
      beforeRouteUpdate(to, from) {
        // 在当前路由改变，但是该组件被复用时调用
        // 举例来说，对于一个带有动态参数的路径 `/users/:id`，在 `/users/1` 和 `/users/2` 之间跳转的时候，
        // 由于会渲染同样的 `UserDetails` 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 因为在这种情况发生的时候，组件已经挂载好了，导航守卫可以访问组件实例 `this`
      },
      beforeRouteLeave(to, from) {
        // 在导航离开渲染该组件的对应路由时调用
        // 与 `beforeRouteUpdate` 一样，它可以访问组件实例 `this`
      },

*/

/*
  第一：登录鉴权：在没有登录时有些页面是不能放访问的
      
        可以访问：登录页面、404页面  用数组存储可以访问的页面 ==> 白名单
  
  第二: 页面鉴权

        后端思想: 将权限分配给角色，将角色分配给用户，不同的用户因为拥有不同的角色，从而拥有了不同的权限    

        前端思想：
          1.用户登录后，获取权限列表

          2.动态渲染侧边栏

          3.生成动态路由列表（异步路由）
            注意：404页面写在动态添加路由的最后(异步路由添加最后)

  第三: 按钮鉴权
      
      

*/
import router from '@/router'
import { useLoginStore } from '@/stores/login'
import { ElMessage } from 'element-plus'
import { useMenuStore } from '../stores/menu'

const whiteRouter = ['LoginVue', 'NotFound']
router.beforeEach(async (to) => {
  // 判断是否是白名单页面
  if (whiteRouter.includes(to.name as string)) return true

  // 是否登录 ==> 判断是否拥有token
  const loginStore = useLoginStore()
  const token = loginStore.token

  if (token) {
    // 1.用户登录后，获取权限列表
    const menuStore = useMenuStore()
    await menuStore.GET_MENU_LIST()

    // 判断即将进入的页面是否存在 ==> 使用 hasRouter()
    if (router.hasRoute(to.name as string)) return true

    // 动态添加路由
    addAsyncRouter(menuStore.menuList)

    return to.fullPath
  }

  const fullPath = to.fullPath //保证登录之后返回原先浏览的页面

  // 没有登录 | 登录失效
  ElMessage.warning('登录失效，请重新登录')
  return '/LoginVue?redirect=' + fullPath
})

interface IMenuItem {
  id: number
  path: string
  authauthName: string
  children: IMenuItem[]
}

// 动态添加路由
function addAsyncRouter(menuList: IMenuItem[]) {
  menuList.forEach((item: IMenuItem) => {
    item.children.forEach((it: IMenuItem) => {
      const path = it.path.slice(0, 1).toUpperCase() + it.path.slice(1)
      router.addRoute('Home', {
        path: '/Home/' + it.path,
        name: it.path,
        component: () => import(`../views/Home/Children/${path}View.vue`)
      })
    })
  })

  // 添加404页面
  router.addRoute({
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: () => import('@/views/Home/NotFound.vue')
  })
}
